home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / DO.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  26KB  |  1,097 lines

  1. /*    SCCS Id: @(#)do.c    3.0    89/11/20
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. /* Contains code for 'd', 'D' (drop), '>', '<' (up, down) */
  6.  
  7. #include "hack.h"
  8. #ifndef STUPID_CPP
  9. /* fortunately, only errno is used from <errno.h> and all known STUPID_CPPs
  10.  * are on UNIX SYSV and will thus all be using the extern int errno; declared
  11.  * below 
  12.  */
  13. #include <errno.h>
  14. #endif
  15.  
  16. #if defined(DGK)
  17. extern struct finfo fileinfo[];
  18. #else
  19. extern boolean level_exists[];
  20. #endif
  21.  
  22. #ifdef SINKS
  23. # ifdef OVLB
  24. static void FDECL(trycall, (struct obj *));
  25. # endif /* OVLB */
  26. STATIC_DCL void FDECL(dosinkring, (struct obj *));
  27. #endif /* SINKS */
  28. STATIC_PTR int FDECL(drop, (struct obj *));
  29. STATIC_DCL void NDECL(litter);
  30. STATIC_PTR int NDECL(wipeoff);
  31. boolean NDECL(drag_down);
  32.  
  33. #ifdef OVLB
  34.  
  35. static const char NEARDATA drop_types[] = { '0', GOLD_SYM, '#', 0 };
  36.  
  37. int
  38. dodrop() {
  39.     return(drop(getobj(drop_types, "drop")));
  40. }
  41.  
  42. #endif /* OVLB */
  43. #ifdef OVL0
  44.  
  45. /* Used for objects which sometimes do special things when dropped; must be
  46.  * called with the object not in any chain.  Returns 1 if the object is
  47.  * gone.
  48.  */
  49. boolean
  50. flooreffects(obj,x,y)
  51. struct obj *obj;
  52. int x,y;
  53. {
  54.     struct trap *t = t_at(x,y);
  55.     boolean pool = is_pool(x,y);
  56.  
  57.     if(obj->otyp == BOULDER && (pool ||
  58.       (t && (t->ttyp==PIT || t->ttyp==SPIKED_PIT || t->ttyp==TRAPDOOR)))) {
  59.         if (pool) {
  60. #ifdef STRONGHOLD
  61.         if(levl[x][y].typ == DRAWBRIDGE_UP)
  62.             levl[x][y].drawbridgemask |= DB_FLOOR;
  63.         else
  64. #endif
  65.             levl[x][y].typ = ROOM;
  66.         if (cansee(x,y))
  67.           pline("There is a large splash as the boulder fills the %s.",
  68.             (levl[x][y].typ==POOL) ? "pool" : "moat");
  69.         else if (flags.soundok)
  70.             You("hear a splash.");
  71.         } else if (t) {
  72.         if(is_maze_lev
  73. #ifdef STRONGHOLD
  74.              && (dlevel > stronghold_level)
  75. #endif
  76.             && t->ttyp == TRAPDOOR) return FALSE;
  77.         if (Blind) You("hear the boulder roll.");
  78.         else pline("The boulder %sfills a %s.",
  79.             t->tseen ? "" : "triggers and ",
  80.             t->ttyp == TRAPDOOR ? "trap door" : "pit");
  81.         deltrap(t);
  82.         if (u.utrap && x==u.ux && y==u.uy) {
  83.             u.utrap = 0;
  84. #ifdef POLYSELF
  85.             if (!passes_walls(uasmon)) {
  86. #endif
  87.             pline("Unfortunately, you were still in it.");
  88.             losehp(rnd(15),
  89.               self_pronoun("dropped a boulder onto %sself","him"),
  90.               NO_KILLER_PREFIX);
  91. #ifdef POLYSELF
  92.             }
  93. #endif
  94.         }
  95.         }
  96.         obfree(obj, (struct obj *)0);
  97.         mnewsym(x,y);
  98.         if (!vism_at(x,y) && (x != u.ux || y != u.uy || Invisible) && !Blind)
  99.         newsym(x,y);
  100.         return TRUE;
  101.     }
  102.     return FALSE;
  103. }
  104.  
  105. #endif /* OVL0 */
  106. #ifdef OVLB
  107.  
  108. #ifdef ALTARS
  109. void
  110. doaltarobj(obj)  /* obj is an object dropped on an altar */
  111.     register struct obj *obj;
  112. {
  113.     if (Blind) return;
  114.     if (obj->blessed || obj->cursed) {
  115.         pline("There is %s flash as %s hit%s the altar.",
  116.               an(Hallucination ? hcolor() :
  117.              obj->blessed ? amber : black),
  118.               doname(obj),
  119.               (obj->quan==1) ? "s" : "");
  120.         if (!Hallucination) obj->bknown = 1;
  121.     } else {
  122.         pline("%s land%s on the altar.", Doname2(obj),
  123.             (obj->quan==1) ? "s" : "");
  124.         obj->bknown = 1;
  125.     }
  126. }
  127. #endif
  128.  
  129. #ifdef SINKS
  130. static
  131. void
  132. trycall(obj)
  133. register struct obj *obj;
  134. {
  135.     if(!objects[obj->otyp].oc_name_known &&
  136.        !objects[obj->otyp].oc_uname)
  137.        docall(obj);
  138. }
  139.  
  140. STATIC_OVL
  141. void
  142. dosinkring(obj)  /* obj is a ring being dropped over a kitchen sink */
  143. register struct obj *obj;
  144. {
  145.     register struct obj *otmp,*otmp2;
  146.     register boolean ideed = TRUE;
  147.  
  148.     You("drop %s down the drain.", doname(obj));
  149.     switch(obj->otyp) {    /* effects that can be noticed without eyes */
  150.         case RIN_SEARCHING:
  151.         You("thought your %s got lost in the sink, but there it is!",
  152.             xname(obj));
  153.         dropx(obj);
  154.         trycall(obj);
  155.         return;
  156.         case RIN_LEVITATION:
  157.         pline("The sink quivers upward for a moment.");
  158.         break;
  159.         case RIN_POISON_RESISTANCE:
  160. #ifdef TUTTI_FRUTTI
  161.         You("smell rotten %s.", makeplural(pl_fruit));
  162. #else
  163.         You("smell rotten fruit.");
  164. #endif
  165.         break;
  166.         case RIN_AGGRAVATE_MONSTER:
  167.         pline("Several flies buzz angrily around the sink.");
  168.         break;
  169.         case RIN_SHOCK_RESISTANCE:
  170.         pline("Static electricity surrounds the sink.");
  171.         break;
  172.         case RIN_CONFLICT:
  173.         You("hear loud noises coming from the drain.");
  174.         break;
  175.         case RIN_GAIN_STRENGTH:
  176.         pline("The water flow seems %ser now.",
  177.             (obj->spe<0) ? "weak" : "strong");
  178.         break;
  179.         case RIN_INCREASE_DAMAGE:
  180.         pline("The water's force seems %ser now.",
  181.             (obj->spe<0) ? "small" : "great");
  182.         break;
  183.         default:
  184.         ideed = FALSE;
  185.         break;
  186.     }
  187.     if(!Blind && !ideed) {
  188.         ideed = TRUE;
  189.         switch(obj->otyp) {        /* effects that need eyes */
  190.         case RIN_ADORNMENT:
  191.             pline("The faucets flash brightly for a moment.");
  192.             break;
  193.         case RIN_REGENERATION:
  194.             pline("The sink looks as good as new.");
  195.             break;
  196.         case RIN_INVISIBILITY:
  197.             You("don't see anything happen to the sink.");
  198.             break;
  199.         case RIN_SEE_INVISIBLE:
  200.             You("see some air in the sink.");
  201.             break;
  202.         case RIN_STEALTH:
  203.         pline("The sink seems to blend into the floor for a moment.");
  204.             break;
  205.         case RIN_HUNGER:
  206.             ideed = FALSE;
  207.             for(otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp2) {
  208.             otmp2 = otmp->nexthere;
  209.             if(otmp != uball && otmp != uchain) {
  210.                 pline("Suddenly, %s vanishes from the sink!",
  211.                             doname(otmp));
  212.                 delobj(otmp);
  213.                 ideed = TRUE;
  214.             }
  215.             }
  216.             break;
  217.         case RIN_FIRE_RESISTANCE:
  218.         pline("The hot water faucet flashes brightly for a moment.");
  219.             break;
  220.         case RIN_COLD_RESISTANCE:
  221.         pline("The cold water faucet flashes brightly for a moment.");
  222.             break;
  223.         case RIN_PROTECTION_FROM_SHAPE_CHAN:
  224.             pline("The sink looks nothing like a fountain.");
  225.             break;
  226.         case RIN_PROTECTION:
  227.             pline("The sink glows %s for a moment.",
  228.                 Hallucination ? hcolor() :
  229.                 (obj->spe<0) ? black : silver);
  230.             break;
  231.         case RIN_WARNING:
  232.             pline("The sink glows %s for a moment.",
  233.                 Hallucination ? hcolor() : white);
  234.             break;
  235.         case RIN_TELEPORTATION:
  236.             pline("The sink momentarily vanishes.");
  237.             break;
  238.         case RIN_TELEPORT_CONTROL:
  239.         pline("The sink looks like it is being beamed aboard somewhere.");
  240.             break;
  241. #ifdef POLYSELF
  242.         case RIN_POLYMORPH:
  243.             pline("The sink momentarily looks like a fountain.");
  244.             break;
  245.         case RIN_POLYMORPH_CONTROL:
  246.     pline("The sink momentarily looks like a regularly erupting geyser.");
  247.             break;
  248. #endif
  249.         }
  250.     }
  251.     if(ideed)
  252.         trycall(obj);
  253.     else
  254.         You("hear the ring bouncing down the drainpipe.");
  255.     if (!rn2(20)) {
  256.         pline("The sink backs up, leaving %s.", doname(obj));
  257.         dropx(obj);
  258.     }
  259.     else
  260.         useup(obj);
  261. }
  262. #endif
  263.  
  264. #endif /* OVLB */
  265. #ifdef OVL0
  266.  
  267. /* some common tests when trying to drop or throw items */
  268. boolean
  269. canletgo(obj,word)
  270. register struct obj *obj;
  271. register const char *word;
  272. {
  273.     if(obj->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)){
  274.            if (*word)
  275.             You("cannot %s something you are wearing.",word);
  276.         return(FALSE);
  277.     }
  278.     if (obj->otyp == LOADSTONE && obj->cursed) {
  279.         if (*word)
  280.             pline("For some reason, you cannot %s the stone%s!",
  281.                 word,
  282.                       plur((long)obj->quan));
  283.         /* Kludge -- see invent.c */
  284.         if (obj->corpsenm) {
  285.             struct obj *otmp;
  286.  
  287.             otmp = obj;
  288.             obj = obj->nobj;
  289.             obj->quan += otmp->quan;
  290.             obj->owt = weight(obj);
  291.             freeinv(otmp);
  292.             obfree(otmp, obj);
  293.         }
  294.         obj->bknown = 1;
  295.         return(FALSE);
  296.     }
  297. #ifdef WALKIES
  298.     if (obj->otyp == LEASH && obj->leashmon != 0) {
  299.            if (*word)
  300.             pline ("The leash is tied around your %s.",
  301.                     body_part(HAND));
  302.         return(FALSE);
  303.     }
  304. #endif
  305.     return(TRUE);
  306. }
  307.  
  308. STATIC_PTR
  309. int
  310. drop(obj) register struct obj *obj; {
  311.     if(!obj) return(0);
  312.     if(obj->olet == GOLD_SYM) {        /* pseudo object */
  313.         register long amount = OGOLD(obj);
  314.  
  315. /* Fix bug with dropping huge amounts of gold read as negative    KAA */
  316.         if(amount < 0) {
  317.             u.ugold += amount;
  318.     pline("The LRS would be very interested to know you have that much.");
  319.         } else {
  320.             /* uswallow test added by GAN 01/29/87 */
  321.             if(flags.verbose)
  322.                 You("drop %ld gold piece%s.",
  323.                    amount, plur(amount));
  324.             if(u.uswallow)
  325.                 (u.ustuck)->mgold += amount;
  326.             else {
  327.                 mkgold(amount, u.ux, u.uy);
  328.                 if(Invisible) newsym(u.ux, u.uy);
  329.             }
  330.         }
  331.         free((genericptr_t) obj);
  332.         return(1);
  333.     }
  334.     if(!canletgo(obj,"drop"))
  335.         return(0);
  336.     if(obj == uwep) {
  337.         if(welded(uwep)) {
  338.             weldmsg(obj, FALSE);
  339.             return(0);
  340.         }
  341.         setuwep((struct obj *)0);
  342.         if(uwep) return 0; /* lifesaved and rewielded */
  343.     }
  344. #ifdef SINKS
  345.     if((obj->olet == RING_SYM) && IS_SINK(levl[u.ux][u.uy].typ)
  346.                             && !u.uswallow) {
  347.         dosinkring(obj);
  348.         return(1);
  349.     }
  350. #endif
  351. #ifdef ALTARS
  352.     if (IS_ALTAR(levl[u.ux][u.uy].typ) && !u.uswallow) {
  353.         /* turn water into [(un)holy] water */
  354.         if (obj->otyp == POT_WATER) {
  355.             obj->blessed = !!(levl[u.ux][u.uy].altarmask & A_LAW);
  356.             obj->cursed =
  357.                 !(levl[u.ux][u.uy].altarmask & (A_LAW | A_NEUTRAL));
  358.         }
  359.         doaltarobj(obj);    /* set bknown */
  360.     } else
  361. #endif
  362.     if(flags.verbose) You("drop %s.", doname(obj));
  363.     dropx(obj);
  364.     return(1);
  365. }
  366.  
  367. /* Called in several places - should not produce texts */
  368. void
  369. dropx(obj)
  370. register struct obj *obj;
  371. {
  372.     freeinv(obj);
  373.     dropy(obj);
  374. }
  375.  
  376. void
  377. dropy(obj)
  378. register struct obj *obj;
  379. {
  380.     if (flooreffects(obj,u.ux,u.uy)) return;
  381. #ifdef WORM
  382.     if(obj->otyp == CRYSKNIFE)
  383.         obj->otyp = WORM_TOOTH;
  384. #endif
  385.     /* uswallow check done by GAN 01/29/87 */
  386.     if(u.uswallow)
  387.         mpickobj(u.ustuck,obj);
  388.     else  {
  389.         obj->nobj = fobj;
  390.         fobj = obj;
  391.         place_object(obj, u.ux, u.uy);
  392.         if(Invisible) newsym(u.ux,u.uy);
  393.         if(obj != uball) sellobj(obj);
  394.         stackobj(obj);
  395.     }
  396. }
  397.  
  398. /* drop several things */
  399. int
  400. doddrop() {
  401.     return(ggetobj("drop", drop, 0));
  402. }
  403.  
  404. #endif /* OVL0 */
  405. #ifdef OVL2
  406.  
  407. #ifdef STRONGHOLD
  408. static boolean NEARDATA at_ladder = FALSE;    /* on a ladder, used in goto_level */
  409. #endif
  410.  
  411. int
  412. dodown()
  413. {
  414.     struct trap *trap = 0;
  415.  
  416.     if((u.ux != xdnstair || u.uy != ydnstair)
  417. #ifdef STRONGHOLD
  418.        && (!xdnladder || u.ux != xdnladder || u.uy != ydnladder)
  419. #endif
  420.       ) {
  421.         if (!(trap = t_at(u.ux,u.uy)) || trap->ttyp != TRAPDOOR
  422.             || (is_maze_lev
  423. #ifdef STRONGHOLD
  424.                 && (dlevel > stronghold_level)
  425. #endif
  426.                                 )
  427.                             || !trap->tseen) {
  428.             You("can't go down here.");
  429.             return(0);
  430.         }
  431.     }
  432.     if(u.ustuck) {
  433.         You("are being held, and cannot go down.");
  434.         return(1);
  435.     }
  436.     if(Levitation) {
  437.         pline("You're floating high above the %s.",
  438.             levl[u.ux][u.uy].typ == STAIRS ? "stairs" :
  439. #ifdef STRONGHOLD
  440.             levl[u.ux][u.uy].typ == LADDER ? "ladder" :
  441. #endif
  442.             "trap door");
  443.         return(0);
  444.     }
  445.  
  446. #ifdef WALKIES
  447.     if(!next_to_u()) {
  448.         You("are held back by your pet!");
  449.         return(0);
  450.     } else {
  451. #endif
  452.         unsee();
  453. #ifdef STRONGHOLD
  454.         if (levl[u.ux][u.uy].typ == LADDER) at_ladder = TRUE;
  455. #endif
  456.         if (trap)
  457. #ifdef POLYSELF
  458.             You("%s into the trap door.",
  459.                 locomotion(uasmon, "jump"));
  460. #else
  461.             You("jump into the trap door.");
  462. #endif
  463.         goto_level(dlevel+1, !trap, TRUE);
  464. #ifdef STRONGHOLD
  465.         at_ladder = FALSE;
  466. #endif
  467. #ifdef WALKIES
  468.     }
  469. #endif
  470.     return(1);
  471. }
  472.  
  473. int
  474. doup()
  475. {
  476.     if((u.ux != xupstair || u.uy != yupstair)
  477. #ifdef STRONGHOLD
  478.        && (!xupladder || u.ux != xupladder || u.uy != yupladder)
  479. #endif
  480.       ) {
  481.         You("can't go up here.");
  482.         return(0);
  483.     }
  484.     if(u.ustuck) {
  485.         You("are being held, and cannot go up.");
  486.         return(1);
  487.     }
  488. #ifdef POLYSELF
  489.     /* Some monsters have carrying capacities less than 5, and we don't
  490.      * want to totally keep them from going upstairs.
  491.      */
  492.     if((invent || u.ugold) && inv_weight() + 5 > 0) {
  493. #else
  494.     if(inv_weight() + 5 > 0) {
  495. #endif
  496.         /* No levitation check; inv_weight() already allows for it */
  497. #ifdef STRONGHOLD
  498.         Your("load is too heavy to climb the %s.",
  499.               levl[u.ux][u.uy].typ == STAIRS ? "stairs" : "ladder");
  500. #else
  501.         Your("load is too heavy to climb the stairs.");
  502. #endif
  503.         return(1);
  504.     }
  505.     if (dlevel == 1) {
  506. #ifdef MACOS
  507.         if(!flags.silent) SysBeep(20);
  508.         if(UseMacAlertText(128,
  509.             "Beware, there will be no return!  Still climb?") != 1) {
  510.             return 0;
  511.         }
  512. #else
  513.         pline("Beware, there will be no return!  Still climb? ");
  514.         if (yn() != 'y') return(0);
  515. #endif /* MACOS */
  516.     }
  517. #ifdef WALKIES
  518.     if(!next_to_u()) {
  519.         You("are held back by your pet!");
  520.         return(0);
  521.     } else {
  522. #endif
  523.         unsee();
  524. #ifdef STRONGHOLD
  525.         if (levl[u.ux][u.uy].typ == LADDER) at_ladder = TRUE;
  526.         goto_level(dlevel-1, 
  527.             (dlevel-1 < stronghold_level || (at_ladder && 
  528.                dlevel-1 >= tower_level && dlevel-1 < tower_level+2)),
  529.                FALSE);
  530.         at_ladder = FALSE;
  531. #else
  532.         goto_level(dlevel-1, (dlevel-1 <= medusa_level), FALSE);
  533. #endif
  534. #ifdef WALKIES
  535.     }
  536. #endif
  537.     return(1);
  538. }
  539.  
  540. #endif /* OVL2 */
  541. #ifdef OVLB
  542.  
  543. STATIC_OVL
  544. void
  545. litter()
  546. {
  547.     struct obj *otmp = invent, *nextobj;
  548.     int capacity = weight_cap();
  549.  
  550.     while (otmp) {
  551.         nextobj = otmp->nobj;
  552.         if ((otmp != uball) && (rnd(capacity) <= otmp->owt)) {
  553.             if (otmp == uwep)
  554.                 setuwep((struct obj *)0);
  555.             if ((otmp != uwep) && (canletgo(otmp, ""))) {
  556.                 Your("%s you down the stairs.",
  557.                      aobjnam(otmp, "follow"));
  558.                 dropx(otmp);
  559.             }
  560.         }
  561.         otmp = nextobj;
  562.     }
  563. }
  564.  
  565. boolean
  566. drag_down()
  567. {
  568.     boolean forward;
  569.     uchar dragchance = 3;
  570.  
  571.  
  572.     /* 
  573.         Assume that the ball falls forward if:
  574.  
  575.         a) the character is wielding it, or
  576.         b) the character has both hands available to hold it (i.e. is 
  577.            not wielding any weapon), or 
  578.         c) (perhaps) it falls forward out of his non-weapon hand
  579.     */
  580.  
  581.     forward = (!(carried(uball))? 
  582.           FALSE : ((uwep == uball) || (!uwep))? 
  583.               TRUE : (boolean)(rn2(3) / 2));
  584.  
  585.     if (carried(uball)) 
  586.         You("lose your grip on the iron ball.");
  587.  
  588.     if(forward) {
  589.         if(rn2(6)) {
  590.             You("get dragged downstairs by the iron ball.");
  591.             losehp(rnd(6), "dragged downstairs by an iron ball",
  592.                 NO_KILLER_PREFIX);
  593.             return(TRUE);
  594.         }
  595.     } else {
  596.         if(rn2(2)) {
  597.             pline("The iron ball smacks into you!");
  598.             losehp(rnd(20), "iron ball collision", KILLED_BY_AN);
  599.             dragchance -= 2;
  600.         } 
  601.         if(dragchance >= rnd(6)) {
  602.             You("get dragged downstairs by the iron ball.");
  603.             losehp(rnd(3), "dragged downstairs by an iron ball",
  604.                 NO_KILLER_PREFIX);
  605.             return(TRUE);
  606.         }
  607.     }
  608.     return(FALSE);
  609. }
  610.  
  611. #endif /* OVLB */
  612. #ifdef OVL2
  613.  
  614. int save_dlevel = 0;
  615.  
  616. void
  617. goto_level(newlevel, at_stairs, falling)
  618. register int newlevel;
  619. register boolean at_stairs, falling;
  620. {
  621.     register int fd;
  622.     register boolean up = (newlevel < dlevel);
  623.  
  624. #ifdef ENDGAME
  625.     if(dlevel == ENDLEVEL) return;    /* To be on the safe side.. */
  626. #endif
  627.     if(newlevel > MAXLEVEL) newlevel = MAXLEVEL;
  628.     if(newlevel <= 0)
  629. #ifdef ENDGAME
  630.         if(u.uhave_amulet)
  631.         newlevel = ENDLEVEL;    /* Endgame Level !!! */
  632.         else
  633. #endif
  634.         done(ESCAPED);        /* in fact < 0 is impossible */
  635.  
  636. #ifdef MACOS
  637.     freeSegs(&segments);
  638. #endif
  639. /*    If you have the amulet and are trying to get out of Hell, going
  640.  *    up a set of stairs sometimes does some very strange things!
  641.  */
  642. #ifdef HARD
  643.     if(Inhell && up && !at_ladder &&
  644.             (dlevel < MAXLEVEL-3) && u.uhave_amulet) {
  645.         int olev = newlevel;
  646.  
  647.         newlevel = (rn2(4) ? newlevel :
  648. /* neutral */         !u.ualigntyp ? (rn2(2) ? dlevel : dlevel + (rnd(5) - 2)) :
  649. /* lawful */         (u.ualigntyp == U_LAWFUL) ? dlevel + (rnd(5) - 2) :
  650. /* chaotic */         dlevel);
  651.         if(newlevel < 1) newlevel = dlevel;
  652.         if(newlevel != olev)
  653.             pline("A mysterious force momentarily surrounds you...");
  654.         if(newlevel == dlevel) {
  655.         (void) dotele();
  656.         return;
  657.         }
  658.     }
  659. #endif /* HARD /* */
  660.     if(newlevel == dlevel) return;          /* this can happen */
  661. #ifdef STRONGHOLD
  662.     /* In Nethack 3.0, Hell starts after the stronghold.  Moreover,
  663.      * there are traps in the stronghold, that can send the player
  664.      * to hell (gnark, gnark)!  So we have to test here:
  665.      */
  666.     if(!Inhell && newlevel > stronghold_level && !up && !at_ladder
  667. # ifdef ENDGAME
  668.     && newlevel < ENDLEVEL
  669. # endif
  670.     ) {
  671. #else
  672.     if(!Inhell && newlevel >= HELLLEVEL && !up) {
  673. #endif /* STRONGHOLD /**/
  674.         You("arrive at the center of the earth...");
  675.         pline("Unfortunately, it is here that hell is located.");
  676. #ifdef MSDOS
  677.         (void) fflush(stdout);
  678. #endif
  679.         if(Fire_resistance) {
  680.         pline("But the fire doesn't seem to harm you.");
  681.         } else {
  682.         save_dlevel = dlevel;
  683.         You("burn to a crisp.");
  684.         You("die...");
  685.         dlevel = maxdlevel = newlevel;
  686.         killer_format = KILLED_BY_AN;
  687.         killer = "visit to hell";
  688.         done(BURNING);
  689.         dlevel = newlevel = save_dlevel; /* in case they survive */
  690.         save_dlevel = 0;
  691.         }
  692.     }
  693.  
  694.     glo(dlevel);
  695. #ifdef MSDOS
  696.     /* Use O_TRUNC to force the file to be shortened if it already
  697.      * exists and is currently longer.
  698.      */
  699.     fd = open(lock, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FCMASK);
  700. #else
  701. # ifdef MACOS
  702.     {
  703.         Str255    fileName;
  704.         OSErr    er;
  705.         short    refNum;
  706.         struct term_info    *t;
  707.         extern WindowPtr    HackWindow;
  708.         
  709.         t = (term_info *)GetWRefCon(HackWindow);
  710.         fileName[0] = (char)strlen(lock);
  711.         Strcpy((char *)&fileName[1],lock);
  712.         if (FSOpen(fileName, t->system.sysVRefNum, &refNum)) {
  713.                 if (er = Create(&fileName,t->system.sysVRefNum,
  714.                             CREATOR,LEVEL_TYPE))
  715.                     SysBeep(20);
  716.         } else {
  717.             (void)SetEOF(refNum,0L);
  718.             (void)FSClose(refNum);
  719.         }
  720.         SetVol(0L,t->system.sysVRefNum);
  721.         fd = open(lock,O_WRONLY | O_BINARY | ((er) ? O_CREAT : 0));
  722.     }
  723. # else
  724.     fd = creat(lock, FCMASK);
  725. # endif /* MACOS */
  726. #endif
  727.     if(fd < 0) {
  728.         /*
  729.          * This is not quite impossible: e.g., we may have
  730.          * exceeded our quota. If that is the case then we
  731.          * cannot leave this level, and cannot save either.
  732.          * Another possibility is that the directory was not
  733.          * writable.
  734.          */
  735. #ifdef DGK
  736.         pline("Cannot create level file '%s'.", lock);
  737. #else
  738.         pline("A mysterious force prevents you from going %s.",
  739.             up ? "up" : "down");
  740. #endif
  741.         return;
  742.     }
  743.  
  744. #ifdef DGK
  745.     if (!savelev(fd, dlevel, COUNT)) {
  746. # ifdef ZEROCOMP
  747.         bflush(fd);
  748. # endif
  749.         (void) close(fd);
  750.         (void) unlink(lock);
  751.         pline("NetHack is out of disk space for making levels!");
  752.         You("can save, quit, or continue playing.");
  753.         return;
  754.     }
  755. #endif
  756.     if(Punished) unplacebc();
  757.     u.utrap = 0;                /* needed in level_tele */
  758.     u.ustuck = 0;                /* idem */
  759.     keepdogs();
  760.     seeoff(1);
  761.     if(u.uswallow)                /* idem */
  762.         u.uswldtim = u.uswallow = 0;
  763.     flags.nscrinh = 1;
  764.     u.ux = u.ux0 = FAR;                /* hack */
  765.     (void) inshop();            /* probably was a trap door */
  766.  
  767. #ifdef DGK
  768. # ifdef ZEROCOMP
  769.     bflush(fd);    /* forget buffer */
  770. # endif
  771.     savelev(fd,dlevel, WRITE);
  772. #else
  773.     savelev(fd,dlevel);
  774. #endif
  775. #ifdef ZEROCOMP
  776.     bflush(fd);    /* flush buffer */
  777. #endif
  778.     (void) close(fd);
  779. #ifdef REINCARNATION
  780.     if (newlevel == rogue_level || dlevel == rogue_level) {
  781.         /* No graphics characters on Rogue levels */
  782.         if (dlevel != rogue_level) {
  783.             (void) memcpy((genericptr_t)savesyms,
  784.                       (genericptr_t)showsyms, sizeof savesyms);
  785.             (void) memcpy((genericptr_t)showsyms,
  786.                       (genericptr_t)defsyms, sizeof showsyms);
  787.             showsyms[S_vodoor] = showsyms[S_hodoor] = 
  788.                 showsyms[S_ndoor] = '+';
  789.         }
  790.         if (newlevel != rogue_level)
  791.             (void) memcpy((genericptr_t)showsyms,
  792.                       (genericptr_t)savesyms, sizeof showsyms);
  793.     }
  794. #endif
  795.     dlevel = newlevel;
  796.     if(maxdlevel < dlevel)
  797.         maxdlevel = dlevel;
  798.     glo(dlevel);
  799.     if(
  800. # ifdef ENDGAME
  801.        dlevel == ENDLEVEL ||
  802. # endif
  803. #if defined(DGK)
  804.     /* If the level has no .where yet, it hasn't been made */
  805.        !fileinfo[dlevel].where)
  806. #else
  807.        !level_exists[dlevel])
  808. #endif
  809.         mklev();
  810.     else {
  811. #if defined(DGK)
  812.         /* If not currently accessible, swap it in. */
  813.         if (fileinfo[dlevel].where != ACTIVE)
  814.             swapin_file(dlevel);
  815. #endif
  816. #if (defined(MSDOS) && !defined(TOS)) || defined(MACOS)
  817.         if((fd = open(lock, O_RDONLY | O_BINARY)) < 0) {
  818. #else
  819.         if((fd = open(lock,0)) < 0) {
  820. #endif
  821.             extern int errno;
  822.             pline("Cannot open \"%s\" (errno %d).", lock, errno);
  823.             pline("Probably someone removed it.");
  824.             done(TRICKED);
  825.         }
  826. #ifdef ZEROCOMP
  827.         minit();
  828. #endif
  829.         getlev(fd, hackpid, dlevel, FALSE);
  830.         (void) close(fd);
  831.     }
  832.  
  833. #ifdef MACOS
  834.     {
  835.         OSErr    er;
  836.         struct term_info    *t;
  837.         extern WindowPtr    HackWindow;
  838.         
  839.         t = (term_info *)GetWRefCon(HackWindow);
  840.         SetVol(0L,t->system.sysVRefNum);
  841.     }
  842. #endif
  843. #ifdef ENDGAME
  844.     if(dlevel != ENDLEVEL)
  845. #endif
  846.     if(at_stairs) {
  847.         if(up) {
  848. #ifdef STRONGHOLD
  849.         if (!at_ladder) {
  850. #endif
  851.             u.ux = xdnstair;
  852.             u.uy = ydnstair;
  853. #ifdef STRONGHOLD
  854.         } else {
  855.             u.ux = xdnladder;
  856.             u.uy = ydnladder;
  857.         }
  858. #endif
  859. /* Remove bug which crashes with levitation/punishment  KAA */
  860.         if(Punished) {
  861.             if(!Levitation)
  862. #ifdef STRONGHOLD
  863.             pline("With great effort you climb the %s.",
  864.                   !at_ladder ? "stairs" : "ladder");
  865. #else
  866.             pline("With great effort you climb the stairs.");
  867. #endif
  868.             placebc(1);
  869.         }
  870.         } else {
  871. #ifdef STRONGHOLD
  872.         if (!at_ladder) {
  873. #endif
  874.             u.ux = xupstair;
  875.             u.uy = yupstair;
  876. #ifdef STRONGHOLD
  877.         } else {
  878.             u.ux = xupladder;
  879.             u.uy = yupladder;
  880.         }
  881. #endif
  882.         if(at_stairs && !up && ((inv_weight() + 5 > 0) || 
  883.                     Punished || Fumbling)) {
  884. #ifdef STRONGHOLD
  885.             You("fall down the %s.",
  886.                 !at_ladder ? "stairs" : "ladder");
  887. #else
  888.             You("fall down the stairs.");
  889. #endif
  890.             if (Punished) {
  891.                 if (drag_down())
  892.                     litter();
  893.                 if (carried(uball)) {
  894.                     if (uwep == uball)
  895.                         setuwep((struct obj *)0);
  896.                     if (uwep != uball)
  897.                         freeinv(uball);
  898.                 }
  899.                 placebc(1);
  900.             } 
  901.             losehp(rnd(3), "falling downstairs", KILLED_BY);
  902.             selftouch("Falling, you");
  903.         }
  904.         }
  905.     } else {    /* trap door or level_tele */
  906.         register int tryct = 0;
  907.         do {
  908. #ifdef STRONGHOLD
  909.         /* Prevent teleport-landing inside the castle */
  910.         if(dlevel == stronghold_level) {
  911.             if(up) u.ux = (COLNO - rnd(8));
  912.             else u.ux = rnd(6);
  913.         }
  914.         else
  915.         /* Prevent teleport-landing inside Vlad's tower */
  916.         if(dlevel >= tower_level && dlevel <= tower_level+2) {
  917.             do {
  918.                 u.ux = rnd(COLNO-1);
  919.             } while (u.ux > 29 && u.ux < 47); 
  920.         }
  921.         else
  922. #endif
  923.         u.ux = rnd(COLNO-1);
  924.         u.uy = rn2(ROWNO);
  925.         } while(tryct++ < 100 && (levl[u.ux][u.uy].typ != ROOM &&
  926.              levl[u.ux][u.uy].typ != CORR) || MON_AT(u.ux, u.uy));
  927.         if(tryct >= 100)
  928.         panic("goto_level: could not relocate player!");
  929.         if(Punished) {
  930.         if(falling) {
  931.             boolean gets_hit;
  932.  
  933.             gets_hit = (uwep == uball)? FALSE : (boolean)rn2(5);
  934.             if (carried(uball)) {
  935.                 pline("Startled, you drop the iron ball.");
  936.                 if (uwep == uball)
  937.                     setuwep((struct obj *)0);
  938.                 if (uwep != uball)
  939.                     freeinv(uball);
  940.             } 
  941.             if(gets_hit){
  942.                     pline("The iron ball falls on your %s.",
  943.                     body_part(HEAD));
  944.                 if (uarmh)
  945.                     Your("helmet doesn't help too much...");
  946.                 losehp(rnd(25),
  947.                     "Crunched in the head by an iron ball",
  948.                     NO_KILLER_PREFIX);
  949.             }
  950.         }
  951.         placebc(1);
  952.         }
  953.         if(falling)
  954.         selftouch("Falling, you");
  955.     }
  956.     (void) inshop();
  957.     initrack();
  958.  
  959.     losedogs();
  960.     if(MON_AT(u.ux, u.uy)) mnexto(m_at(u.ux, u.uy));
  961.     if(MON_AT(u.ux, u.uy)) {
  962.         impossible("mnexto failed (do.c)?");
  963.         rloc(m_at(u.ux, u.uy));
  964.     }
  965.     flags.nscrinh = 0;
  966.     setsee();
  967.     seeobjs();    /* make old cadavers disappear - riv05!a3 */
  968.     docrt();
  969.     if(!flags.nopick && (OBJ_AT(u.ux, u.uy) || levl[u.ux][u.uy].gmask))
  970.         pickup(1);
  971.     else read_engr_at(u.ux,u.uy);
  972. #ifdef HARD
  973.     /* Final confrontation */
  974.     if (dlevel == 1 && u.uhave_amulet && flags.no_of_wizards == 0)
  975.         resurrect();
  976. #endif
  977.     is_maze_lev = (rooms[0].hx < 0
  978. #ifdef STRONGHOLD
  979.         || dlevel == stronghold_level
  980.         || (dlevel >= tower_level && dlevel <= tower_level + 2)
  981. #endif
  982. #ifdef ENDGAME
  983.         || dlevel == ENDLEVEL
  984. #endif
  985.         );
  986. #ifdef MACOS
  987.     freeSegs(&segments);
  988.     segments = SEG_DO;
  989. #endif
  990. }
  991.  
  992. #endif /* OVL2 */
  993. #ifdef OVL3
  994.  
  995. int
  996. donull() {
  997.     return(1);    /* Do nothing, but let other things happen */
  998. }
  999.  
  1000. #endif /* OVL3 */
  1001. #ifdef OVLB
  1002.  
  1003. STATIC_PTR int
  1004. wipeoff() {
  1005.     if(u.ucreamed < 4)    u.ucreamed = 0;
  1006.     else            u.ucreamed -= 4;
  1007.     if (Blinded < 4)    Blinded = 0;
  1008.     else            Blinded -= 4;
  1009.     if (!Blinded) {
  1010.         pline("You've got the glop off.");
  1011.         u.ucreamed = 0;
  1012.         make_blinded(0L,TRUE);
  1013.         return(0);
  1014.     } else if (!u.ucreamed) {
  1015.         Your("%s feels clean now.", body_part(FACE));
  1016.         return(0);
  1017.     }
  1018.     return(1);        /* still busy */
  1019. }
  1020.  
  1021. int
  1022. dowipe()
  1023. {
  1024.     if(u.ucreamed)  {
  1025.         static char NEARDATA buf[39];
  1026.  
  1027.         Sprintf(buf, "wiping off your %s", body_part(FACE));
  1028.         set_occupation(wipeoff, buf, 0);
  1029.         /* Not totally correct; what if they change back after now
  1030.          * but before they're finished wiping?
  1031.          */
  1032.         return(1);
  1033.     }
  1034.     Your("%s is already clean.", body_part(FACE));
  1035.     return(1);
  1036. }
  1037.  
  1038. #endif /* OVLB */
  1039. #ifdef OVL1
  1040.  
  1041. /* split obj so that it gets size num */
  1042. /* remainder is put in the object structure delivered by this call */
  1043. struct obj *
  1044. splitobj(obj, num) register struct obj *obj; register int num; {
  1045. register struct obj *otmp;
  1046.     otmp = newobj(obj->onamelth);
  1047.     *otmp = *obj;        /* copies whole structure */
  1048.     otmp->o_id = flags.ident++;
  1049.     obj->quan = num;
  1050.     obj->owt = weight(obj);
  1051.     otmp->quan -= num;
  1052.     otmp->owt = weight(otmp);    /* -= obj->owt ? */
  1053.     obj->nobj = obj->nexthere = otmp;
  1054.     if (obj->onamelth)
  1055.         (void)strncpy(ONAME(otmp), ONAME(obj), (int)obj->onamelth);
  1056.     if(obj->unpaid) splitbill(obj,otmp);
  1057.     return(otmp);
  1058. }
  1059.  
  1060. #endif /* OVL1 */
  1061. #ifdef OVLB
  1062.  
  1063. void
  1064. set_wounded_legs(side, timex)
  1065. register long side;
  1066. register int timex;
  1067. {
  1068.     if(!Wounded_legs) {
  1069.         ATEMP(A_DEX)--;
  1070.         flags.botl = 1;
  1071.     }
  1072.  
  1073.     if(!Wounded_legs || (Wounded_legs & TIMEOUT))
  1074.         Wounded_legs |= side + timex;
  1075.     else
  1076.         Wounded_legs |= side;
  1077. }
  1078.  
  1079. void
  1080. heal_legs()
  1081. {
  1082.     if(Wounded_legs) {
  1083.         if (ATEMP(A_DEX) < 0) ATEMP(A_DEX)++;
  1084.  
  1085.         if((Wounded_legs & BOTH_SIDES) == BOTH_SIDES) {
  1086.             Your("%s feel somewhat better.",
  1087.                 makeplural(body_part(LEG)));
  1088.         } else {
  1089.             Your("%s feels somewhat better.",
  1090.                 body_part(LEG));
  1091.         }
  1092.         Wounded_legs = 0;
  1093.     }
  1094. }
  1095.  
  1096. #endif /* OVLB */
  1097.